<template>
  <div
    class="data-lineage-custom-node"
    :style="{ opacity: nodeOpacity }"
    @click="toggleSelectTable"
    @mouseenter="mouseenterTable"
    @mouseleave="mouseleaveTable"
  >
    <!-- header -->
    <header class="node-header" :style="headerStyle">
      <a-tooltip :title="nodeData.databaseName">
        <div class="table-type-text text-overflow-ellipsis">
          <a-icon-font
            :type="nodeTableTypeInfo.databaseIcon"
            class="node-icon"
          />
          {{ nodeData.databaseName }}
        </div>
      </a-tooltip>
    </header>

    <!-- 内容 -->
    <main class="node-container">
      <!-- 表名 -->
      <div class="sub-title-container">
        <div
          :title="nodeData.tableName"
          :style="{
            height: `${nodeLineHeight}px`,
            'line-height': `${nodeLineHeight}px`,
          }"
          class="table-name text-overflow-ellipsis"
        >
          {{ nodeData.tableName }}
        </div>
      </div>
    </main>
  </div>
</template>

<script lang="ts">
/**
 * 数据血缘 表格级血缘 自定义 X6 节点
 */
import { Component, Vue, Inject } from 'vue-property-decorator'
import {
  NODE_HEADER_HEIGHT,
  NODE_LINE_HEIGHT,
  TABLE_TYPE_INFO_MAP,
} from './constants'

@Component({
  components: {},
})
export default class FiledLineageNode extends Vue {
  $eventBus: any
  @Inject() getGraph: any
  @Inject() getNode: any
  private nodeHeaderHeight: number = NODE_HEADER_HEIGHT || 24
  private nodeLineHeight: number = NODE_LINE_HEIGHT || 24
  private grayscale: boolean = false // 灰度模式
  private selected: boolean = false //  selected
  private hover: boolean = false // hover
  private clickTimeId: any

  public get nodeData() {
    return this.getNode().data
  }

  public get nodeTableTypeInfo() {
    return TABLE_TYPE_INFO_MAP[this.nodeData.tableType]
  }

  public get tableType() {
    return this.nodeData.tableType
  }

  private get nodeOpacity() {
    const { selected, grayscale } = this
    if (!selected && grayscale) {
      return 0.6
    }
    return 1
  }

  private get headerStyle() {
    const { nodeTableTypeInfo, nodeHeaderHeight, selected, hover } = this
    return {
      background: nodeTableTypeInfo.theme,
      height: `${nodeHeaderHeight}px`,
      'line-height': `${nodeHeaderHeight}px`,
      'border-color':
        selected || hover
          ? nodeTableTypeInfo.selectedBorderColor
          : 'transparent',
      'font-weight': 400,
      color: '#fff',
    }
  }

  private mounted() {
    const self = this as any
    const node: any = this.getNode() as Node
    // 监听数据改变事件
    node.on('change:states', ({ current }: any) => {
      const {
        selected,
        onSelectedHighlightLink,
        onHoverHighlightLink,
        haveHighlightLink,
      } = current
      if (onSelectedHighlightLink || onHoverHighlightLink) {
        self.grayscale = false
      } else {
        self.grayscale = !!haveHighlightLink
      }
      self.selected = selected
    })
  }

  private mouseenterTable() {
    this.hover = true
    this.emitEvent('table-mouseenter')
  }

  private mouseleaveTable() {
    this.hover = false
    this.emitEvent('table-mouseleave')
  }

  private toggleSelectTable() {
    clearTimeout(this.clickTimeId)
    this.clickTimeId = setTimeout(() => {
      this.emitEvent('toggle-selected-table')
    }, 250)
  }

  private emitEvent(eventType: string) {
    this.$eventBus.$emit('table-data-lineage-custom-vue-node-event', {
      databaseName: this.nodeData.databaseName,
      tableName: this.nodeData.tableName,
      eventType,
    })
  }
}
</script>

<style lang="less" scoped>
@import './vue-node.less';
</style>
